﻿using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Reflection.Metadata;

namespace synoexec.synoexec.synologylib.Helpers
{
    public static class FuncHelper
    {
        /// <summary>
        /// 获取方法 类型
        /// </summary>
        public static MethodInfo? GetMethod(object instance, string methodName)
        {
            return instance.GetType().GetMethods().FirstOrDefault(t => t.Name == methodName);
        }
        /// <summary>
        /// 调用泛型方法
        /// </summary>
        public static T? Call<T>(object instance, MethodInfo method_type, Type fx, params object[] args)
        {
            var method = method_type.MakeGenericMethod(fx);
            return (T?)method.Invoke(instance, null);
        }
        public static TOut? Call<TPType, TOut>(object instance, string methodName, params object[] args) where TOut : class
        {
            var method = instance.GetType().GetMethods().FirstOrDefault(t => t.Name == methodName && t.Equals<TPType>());
            if (method != null)
            {
                var o = method.Invoke(instance, args);
                return o as TOut;
            }
            return null;
        }
        public static void Call<TPType>(object instance, string methodName, params object[] args)
        {
            Call<TPType, object>(instance, methodName, args);
        }
        internal static bool Equals<TPType>(this MethodInfo info)
        {
            var typ = info.GetParameters().FirstOrDefault();
            if (typ == null) return false;
            var typ1 = typ.ParameterType;
            var typ2 = typeof(TPType);
            if (typ1 == typ2 || typ1.Name == "object") return true;

            var typ1_1 = typ1.GenericTypeArguments.FirstOrDefault();
            if (typ1_1 != null && typ1_1.Name == typ2.Name) return true;

            return false;
        }
    }
}
